大家好,昨天介紹過 Three.js 中是如何一步一步構築起物件跟環境後,今天我們來聊聊在 3D 環境中的物件操作是如何運作的。
那麼就開始吧~
我們在昨天的文章中有提到在 Three.js 中使用的是右手座標系統,webGL 的重要功能正是將 3D 座標系統經過轉變、投影等計算出最終顯示在設備上的對應位置。
因此,在互動介面或遊戲製作時,我們就會需要知道物體之間的碰撞(Collision Detection)。而在 3D的環境中,物體皆是由表面三角形所組成,因此我們要計算的即是檢查 兩物體的三角形是否有碰撞。
基礎語法:
Raycast(origin, direction, near, far)
名稱 | 說明 |
---|---|
origin | 射線起點向量 |
direction | 射線方向向量 |
near | 射線回傳值,其結果值應比 naer 遠,其值不可為負數,預設值為 0 |
far | 射線回傳值,其結果應比 far 近,far 結果值不可小於 near ,預設值為無限大 |
Raycast 顧名思義就是他會從攝影機方向頭放射線,去偵測射線與哪些物體有交集。
舉例來說,我們想像整個畫面都是攝影機範圍,從攝影機的視角放出射線檢查有無物體跟射線交集,若是有交集,就可以讓物體跟滑鼠做互動。
//宣告raycaster和mouse變數
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseMove( event ) {
//透過滑鼠點選的位置計算出 raycaster 所需要的點的位置,以螢幕中心為原點,值的範圍為-1到1.
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function render() {
// 透過滑鼠點的位置和當前相機的矩陣計算出 raycaster值
raycaster.setFromCamera( mouse, camera );
// 取得 raycaster 射線和所有物件相交的陣列集合
var intersects = raycaster.intersectObjects( scene.children );
// 計算後,將所有有相交的物件的顏色改變為紅色,如果只需要將第一個觸發事件,那就陣列的第一個物件改變顏色即可
for ( var i = 0; i < intersects.length; i++ ) {
intersects[ i ].object.material.color.set( 0xff0000 );
}
renderer.render( scene, camera );
}
window.addEventListener( 'mousemove', onMouseMove, false );
window.requestAnimationFrame(render);
另外,我們在 Raycast 內也有許多 Methods 可以使用,以下簡單介紹幾個:
raycaster.set(origin, direction)
利用新的原點與方向更新射線。
名稱 | 說明 |
---|---|
origin | 射線起點向量 |
direction | 射線方向向量 |
raycaster.setFromCamera(coords, camera)
利用新的原點與方向更新射線
名稱 | 說明 |
---|---|
coords | 滑鼠的 2D 座標,X與Y分量應落在 -1 至 1 之間 |
camera | camera 視角射出射線 |
raycaster.intersectObjects(objects, recursive, optionalTarget)
檢查射線與物件(無論是否有後代元素)有無相交。回傳相交點值,按距離排序,最接近的排序越靠前。
名稱 | 說明 |
---|---|
objects | 欲檢查有無相交的物件 |
recursive | 是否遞迴檢查,若 true 則會檢查物件以及其後代元素,否則只檢查該物件。預設值為 false |
optionalTarget | 非必填選項。設定結果的目標,否則會實例化一個新陣列。若有設置 optionalTarget 則必須在每次調用時清除該陣列。(即array.length = 0) |
今天介紹的是滑鼠在 three.js 中的事件操作,其實乍聽之下有點虛幻。若是腦子裡沒有畫面的話,都可以去官網上看看範例呦。
那麼今天就到這邊,我們明天見!